﻿// -----------------------------------------------------------------------
// <copyright file="StreamReader.cs" company="Company">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------

using System.Runtime.InteropServices;
using System.Text;
using Company.IO.Interfaces;

namespace Company.System.IO
{
    /// <summary>
    /// Implements a TextReader that reads characters from a byte stream in a particular encoding.
    /// </summary>
    [Guid("22cc87d6-de7e-4d6f-bbf4-1406b8c34b97")]
    public class StreamReader : IStreamReader
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="StreamReader"/> class.
        /// </summary>
        /// <param name="systemIoConverter">The system io converter.</param>
        /// <param name="streamReader">The stream reader.</param>
        public StreamReader(ISystemIoConverter systemIoConverter, global::System.IO.StreamReader streamReader)
        {
            SystemConverter = systemIoConverter;
            InternalStreamReader = streamReader;
        }

        #region Implementation of IStreamReader

        /// <summary>
        /// Get or Sets the converter
        /// </summary>
        private ISystemIoConverter SystemConverter { get; set; }

        /// <summary>
        /// Get or Sets the internal stream object
        /// </summary>
        private global::System.IO.StreamReader InternalStreamReader { get; set; }

        /// <summary>
        /// Gets the current character encoding that the current StreamReader object is using.
        /// </summary>
        Encoding IStreamReader.CurrentEncoding
        {
            get { return InternalStreamReader.CurrentEncoding; }
        }

        /// <summary>
        /// Returns the underlying stream.
        /// </summary>
        IStream IStreamReader.BaseStream
        {
            get { return Convert(InternalStreamReader.BaseStream); }
        }

        /// <summary>
        /// Gets a value that indicates whether the current stream position is at the end of the stream.
        /// </summary>
        bool IStreamReader.EndOfStream
        {
            get { return InternalStreamReader.EndOfStream; }
        }

        /// <summary>
        /// Closes the StreamReader object and the underlying stream, and releases any system resources associated with the reader. (Overrides TextReader.Close().)
        /// </summary>
        void IStreamReader.Close()
        {
            InternalStreamReader.Close();
        }

        /// <summary>
        /// Clears the internal buffer.
        /// </summary>
        void IStreamReader.DiscardBufferedData()
        {
            InternalStreamReader.DiscardBufferedData();
        }

        /// <summary>
        /// Returns the next available character but does not consume it. (Overrides TextReader.Peek().)
        /// </summary>
        /// <returns>
        /// An integer representing the next character to be read, or -1 
        /// if there are no characters to be read or if the stream does not support seeking.
        /// </returns>
        int IStreamReader.Peek()
        {
            return InternalStreamReader.Peek();
        }

        /// <summary>
        /// Reads the next character from the input stream and advances the character position by one character. (Overrides TextReader.Read().)
        /// </summary>
        /// <returns>The next character from the input stream represented as an Int32 object, or -1 if no more characters are available.</returns>
        int IStreamReader.Read()
        {
            return InternalStreamReader.Read();
        }

        /// <summary>
        /// Reads a specified maximum of characters from the current stream into a buffer, beginning at the specified index.
        /// </summary>
        /// <param name="buffer">
        /// When this method returns, contains the specified character array with the values between 
        /// index and (index + count - 1) replaced by the characters read from the current source.
        /// </param>
        /// <param name="index">The index of buffer at which to begin writing.</param>
        /// <param name="count">The maximum number of characters to read.</param>
        /// <returns>
        /// The number of characters that have been read, or 0 if at the end of the stream and no data was read. 
        /// The number will be less than or equal to the count parameter, 
        /// depending on whether the data is available within the stream.
        /// </returns>
        int IStreamReader.Read(char[] buffer, int index, int count)
        {
            return InternalStreamReader.Read(buffer, index, count);
        }

        /// <summary>
        /// Reads the stream from the current position to the end of the stream.
        /// </summary>
        /// <returns>The rest of the stream as a string, from the current position to the end. 
        /// If the current position is at the end of the stream, returns an empty string ("").</returns>
        string IStreamReader.ReadToEnd()
        {
            return InternalStreamReader.ReadToEnd();
        }

        /// <summary>
        /// Reads a line of characters from the current stream and returns the data as a string.
        /// </summary>
        /// <returns>The next line from the input stream, or a null reference (Nothing in Visual Basic) if the end of the input stream is reached.</returns>
        string IStreamReader.ReadLine()
        {
            return InternalStreamReader.ReadLine();
        }

        #endregion

        /// <summary>
        /// Converts the specified stream.
        /// </summary>
        /// <param name="stream">The stream.</param>
        /// <returns>The converted object</returns>
        private IStream Convert(global::System.IO.Stream stream)
        {
            return SystemConverter.Convert(stream);
        }
    }
}